package com.hsxc.cdz.monitor.executor;

import com.hsxc.cdz.base.bean.IcUser;
import com.hsxc.cdz.monitor.bean.FeeRate;
import com.hsxc.cdz.monitor.bean.pile.v1_21.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.hsxc.cdz.base.bean.Bill;
import com.hsxc.cdz.base.bean.Pile;
import com.hsxc.cdz.base.dao.SystemDao;
import com.hsxc.cdz.base.util.CommonUtils;
import com.hsxc.cdz.base.util.Constants;
import com.hsxc.cdz.base.util.TimeFormatter;
import com.hsxc.cdz.mgmt.GlobalManager;
import com.hsxc.cdz.mgmt.pile.PileManager;
import com.hsxc.cdz.mgmt.user.IcUserManager;
import com.hsxc.cdz.monitor.ActiveMonitor;
import com.hsxc.cdz.monitor.FSM.CachePile;
import com.hsxc.cdz.monitor.bean.Message;
import com.hsxc.cdz.monitor.bean.MessageNew;
import com.hsxc.cdz.monitor.bean.server.v1_21.CardSerMsg;
import com.hsxc.cdz.monitor.bean.server.v1_21.ChargeCeaseSerMsg;
import com.hsxc.cdz.monitor.bean.server.v1_21.ChargeSerMsg;
import com.hsxc.cdz.monitor.bean.server.v1_21.RegisterSerMsg;
import com.hsxc.cdz.monitor.bean.server.v1_21.ReserveCeaseSerMsg;
import com.hsxc.cdz.trans.bill.BillManager;
import com.hsxc.cdz.trans.bill.CacheTrade;
import com.hsxc.cdz.trans.bill.CacheTrade.TradeStatus;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;

import java.util.Calendar;
import java.util.Random;

/**
 * @author 刘力文 执行与充电桩相关的业务逻辑的类
 */
@Component
public class PileExecutor {

    @Autowired
    private PileManager pileRegister;
    @Autowired
    private SystemDao systemDao;
    @Autowired
    BillManager billManager;
    @Autowired
    IcUserManager icUserManager;

    // Logger
    private static Logger logger = LoggerFactory.getLogger(PileExecutor.class);

    /**
     * 充电桩进行登录
     *
     * @param pileAddress
     * @param operatorNO
     * @param registerContent
     * @return
     */
    public void load(String pileAddress, String operatorNO, RegisterPileMsg registerContent, String lineNum,
                     int pileType, String protocol, ChannelHandlerContext ctx) {

        logger.info("LOADING PILE WITH PILEADDRESS{" + pileAddress + "},OPERATORNO{" + operatorNO + "},PILRTYPE{"
                + pileType + "},PROTOCOL{" + protocol + "}");
        logger.info("now {}", "starting server");
        // 从报文中获取充电桩数据
        Pile pile = new Pile();
        pile.setPileNO(pileAddress);
        pile.setOperatorNO(operatorNO);
        pile.setState(Pile.STATE_IDLE);
        pile.setSoftVersion(registerContent.getVersionNum());
        pile.setDelete(false);
        pile.setAccount(registerContent.getAccount());
        pile.setPassword(registerContent.getPassword());
        pile.setFstLevType(registerContent.getFirstType());
        pile.setScdLevType(registerContent.getSecondType());
        pile.setSn(registerContent.getSN());
        pile.setLongitude(((float) registerContent.getLongitudes()) / 1000000);
        pile.setLatitude(((float) registerContent.getLatitudes()) / 1000000);
        pile.setPhyType(pileType);
        // 检测数据库中是否存在该桩
        Pile check = pileRegister.selPile(pile.getPileNO());
        MessageNew message = new MessageNew();
        message.setIsRegister(Constants.NO_REGISTER);
        message.setResponse(Constants.RESPONSE_NOMAL);
        // 检测充电桩上传数据与数据库数据是否匹配
        // 根据检测结果设定返回充电桩的报文
        logger.info("电桩正在登录，状态为：" + pile.getState());
        if (check != null) {
            if (!check.getAccount().equals(pile.getAccount())) {
                message.setResponse(Constants.RESPONSE_ERROR_ACCOUNT);
            } else if (!check.getPassword().equals(pile.getPassword())) {
                message.setResponse(Constants.RESPONSE_ERROR_PASSWORD);
            } else if (!check.getOperatorNO().equals(operatorNO)) {
                message.setResponse(Constants.RESPONSE_NOMAL);
                logger.info(message.getOperator() + Constants.RESPONSE_NOMAL);
            } else {
                // 将桩的数据放入缓存并更新数据库
                pile.setOperatorNO(check.getOperatorNO());
                pile.setStationNO(check.getStationNO());
                boolean success = GlobalManager.pileManager.loadPile(pile, ctx, protocol, pileType);
                if (!success) {
                    message.setResponse(Constants.RESPONSE_ERROR_RENAME);
                } else {
                    message.setIsRegister(Constants.DID_REGISTER);
                }
            }
        }

        // 生成回复报文体
        RegisterSerMsg regResponse = new RegisterSerMsg();
        regResponse.setOperator(operatorNO);
        regResponse.setAddress(pileAddress);
        regResponse.setSecretKey(13456789);
        regResponse.setVesion(registerContent.getVersionNum());

        String ip = systemDao.selectByName("ipaddress");
        ip = (ip == null) ? "192.198.1.46" : ip;
        regResponse.setIpAdress(ip);
        String port = systemDao.selectByName("port");
        port = (port == null) ? "5000" : port;
        regResponse.setPort(Integer.valueOf(port));
        // 生成回复报文
        message.setAddress(pileAddress);
        message.setContent(regResponse.getBytesFromMessage());
        message.setContentLength(RegisterSerMsg.length);
        message.setFrame(Constants.SERVER_RESPONSE_REGISTER);
        message.setIsOpen(Constants.START_UP);
        message.setLineNum(lineNum);
        message.setOperator(operatorNO);
        message.setPileType(pileType);
        message.setProtocolVersion(protocol);

        ctx.writeAndFlush(message);

        // TODO:是否需要时间间隔？
        // 登录后马上设置二维码，二维码为设备地址的后12个字节（前4个字节为城市区号）
        ServerExecutor.setQRC(pileAddress, pileAddress, protocol, pileType);
    }

    /**
     * 交流桩充电桩进行注册
     *
     * @param pileAddress     充电桩设备地址
     * @param operatorNO      运营商编号
     * @param registerContent 注册报文体
     * @return
     */
    public void register_jiaoliu(String pileAddress, String operatorNO, RegisterPileMsg registerContent, String lineNum,
                                 String protocol, int pileType, ChannelHandlerContext ctx) {
        // 获取充电桩数据
        Pile pile = new Pile();
        pile.setPileNO(pileAddress);
        pile.setOperatorNO(operatorNO);
        pile.setAccount(registerContent.getAccount());
        pile.setPassword(registerContent.getPassword());
        // 生成桩的对象
        pile.setState(Pile.STATE_IDLE);
        pile.setSoftVersion(registerContent.getVersionNum());
        pile.setDelete(false);
        pile.setRegTime(TimeFormatter.toTimeYear());
        pile.setFstLevType(registerContent.getFirstType());
        pile.setScdLevType(registerContent.getSecondType());
        pile.setSn(registerContent.getSN());
        pile.setLongitude(((float) registerContent.getLongitudes()) / 1000000);
        pile.setLatitude(((float) registerContent.getLatitudes()) / 1000000);
        pile.setPhyType(pileType);
        // 无法判断属于私人还是电站

        Pile check = pileRegister.selPile(pile.getPileNO());
        logger.info(pileAddress);

        MessageNew message = new MessageNew();
        message.setIsRegister(Constants.NO_REGISTER);
        message.setResponse(Constants.RESPONSE_NOMAL);
        // 检测充电桩上传数据与数据库数据是否匹配
        // 根据检测结果设定返回充电桩的报文
        if (check != null) {
            if (!check.getAccount().equals(pile.getAccount())) {
                message.setResponse(Constants.RESPONSE_ERROR_ACCOUNT);
            } else if (!check.getPassword().equals(pile.getPassword())) {
                message.setResponse(Constants.RESPONSE_ERROR_PASSWORD);
            } else if (!check.getOperatorNO().equals(operatorNO)) {
                logger.info("协议未给出运营商编号错误码，直接返回正常返回码，但是不能注册成功");
                message.setResponse(Constants.RESPONSE_NOMAL);
            } else {
                boolean success = false;
                success = GlobalManager.pileManager.registerPile(pile, ctx, protocol);
                if (!success) {
                    message.setResponse(Constants.RESPONSE_ERROR_RENAME);
                } else {
                    message.setIsRegister(Constants.DID_REGISTER);
                }
            }
        } else {
            //分配一个电桩编号
            long randomLong = new Random().nextLong();
            //message.setAddress();
        }

        // 生成回复报文
        message.setAddress(pileAddress);
        // message.setContent(regResponse.getBytesFromMessage(registerContent.getProtocolVersion()));
        message.setFrame(Constants.SERVER_RESPONSE_REGISTER);
        message.setIsOpen(Constants.START_UP);
        message.setLineNum(lineNum);
        message.setOperator(operatorNO);
        // 生成服务端回复报文体
        RegisterSerMsg msg = new RegisterSerMsg();
        msg.setAddress(pileAddress);
        msg.setOperator(operatorNO);
        msg.setSecretKey(13456789);
        msg.setVesion(registerContent.getVersionNum());
        String ip = (systemDao.selectByName("ipaddress"));
        ip = (ip == null) ? "192.198.1.46" : ip;
        msg.setIpAdress(ip);
        String port = systemDao.selectByName("port");
        port = (port == null) ? "5000" : port;
        msg.setPort(Integer.valueOf(port));
        // 设置报文长度及报文内容
        message.setContentLength(RegisterSerMsg.length);
        message.setContent(msg.getBytesFromMessage());
        message.setProtocolVersion(protocol);
        message.setPileType(pileType);
        // 写出回复报文
        ctx.writeAndFlush(message);

        // 注册后马上设置二维码，二维码为设备地址的后12个字节（前4个字节为城市区号）
        ServerExecutor.setQRC(pileAddress, pileAddress, protocol, pileType);
    }

    public boolean heart(String pileAddress, HeartPileMsg heart, String lineNum, String protocol, int pileType) {

        Calendar calendar = Calendar.getInstance();
        Calendar calendarPile = TimeFormatter.dateFromString(lineNum);
        long inteval = calendar.getTimeInMillis() - calendarPile.getTimeInMillis();
        long second = new Long(inteval / (1000 * 60));
        if (second > 1) {
            ServerExecutor.checkTime(TimeFormatter.toTimeYear(), pileAddress, protocol, pileType);
        }
        logger.info("心跳设备地址" + pileAddress);
        CachePile cachePile = GlobalManager.pileManager.getPile(pileAddress);
        if (cachePile == null) {
            logger.info("收到心跳时，桩已经断开，无回复心跳报文");
            return false;
        }

        // 更新交易、账单
        GlobalManager.tradeManager.updateTradeByHeart(pileAddress, (double)heart.getElectricity()/100, heart.getSumMoney()/100);
        GlobalManager.billManager.updateBillByHeart(pileAddress, heart.getElectricity()/100, heart.getSumMoney()/100);

		/*
         * TODO: if (heart.getChargeState() == HeartPileMsg.CHARGE_STATE_WORK &&
		 * cachePile.getStatus() != PileMemState.Status.PILE_STATUS_LOCKED) {
		 * cachePile.changeStateCharge(); } if (heart.getChargeState() ==
		 * HeartPileMsg.CHARGE_STATE_IDLE && cachePile.getStatus() !=
		 * PileMemState.Status.PILE_STATUS_LOCKED) {
		 * cachePile.changeStateIdle(); } if (heart.getReserveState() ==
		 * HeartPileMsg.RESERVE_STATE_WORK && cachePile.getStatus() !=
		 * PileMemState.Status.PILE_STATUS_LOCKED) { cachePile.setReserve(true);
		 * }
		 */
        if (!heart.getFaultCode().equals("00")) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    cachePile.setFault(heart.getFaultCode());
                    cachePile.fault();
                }
            }).start();
        }

        // 设置故障码
        MessageNew message = new MessageNew();
        message.setAddress(pileAddress);
        message.setIsOpen(Constants.START_UP);
        message.setIsRegister(Constants.DID_REGISTER);
        message.setLineNum(lineNum);
        message.setOperator(cachePile.getOperator());
        message.setResponse(Constants.RESPONSE_NOMAL);
        message.setFrame(Constants.SERVER_RESPONSE_HEART);
        message.setContentLength(0);
        message.setContent(null);
        message.setPileType(pileType);
        message.setProtocolVersion(protocol);
        Channel channel = cachePile.getChannel();
        if (channel != null) {
            channel.writeAndFlush(message);
            logger.error("收到心跳时，心跳回复发送成功");
            return true;
        } else {
            logger.error("收到心跳时，netty通道已经断开，心跳回复无法发送");
            return false;
        }
    }

    /**
     * @param startContent 开始充电服务器报文
     * @param pileAddress  充电桩设备地址
     * @param lineNum      流水号
     * @return boolean : 成功，失败
     */
    public boolean startCharge(ChargePileMsg startContent, String pileAddress, String lineNum, String protocol,
                               int pileType, String responseCode) {

        logger.info("startContent-->>" + startContent.getCardNum());
        logger.info("pileAddress-->>" + pileAddress);

        CachePile cachePile = GlobalManager.pileManager.getPile(pileAddress);
        if (cachePile == null) {
            logger.error("TRANS:Can't find pile {} for TRANS .", pileAddress);
            return false;
        }
        logger.info("CHARGE CONFIRM ERRCODE IS " + responseCode);
        if (responseCode.equals(Constants.RESPONSE_ERROR_COMMAND)) {
            logger.info("WHEN CONFIRM CHARGE START SUCCESS,RESPONSE CODE IS ERROE! SO PILE IS NOINSERTED");
            CacheTrade cacheTrade = GlobalManager.tradeManager.getTrade(pileAddress, startContent.getCardNum());
            cacheTrade.setTradeStatus(TradeStatus.Trade_STATUS_FAIL);
            GlobalManager.tradeManager.newTrade(cacheTrade);
        } else {
            logger.info("WHEN CONFIRM CHARGE SUCCESS,RESPONSE CODE IS NORMAL" + responseCode);
            // Add to charging list
            if (pileType == 0) {
                ActiveMonitor.addPileToList(cachePile);
            }
            logger.info("START TO CONFIRM CHARGE STARTED   status " + cachePile.getStatus());
            boolean b = cachePile.confirmStart(0, 0, 0, 0, 0, startContent.getOntimeStart(), startContent.getCardNum());
        }
        MessageNew message = new MessageNew();
        message.setIsRegister(Constants.DID_REGISTER);
        // if (b) {
        message.setResponse(Constants.RESPONSE_NOMAL);
        // } else {
        // logger.error("Pile {} confirm start error .", pileAddress);
        // return true;
        // }
        message.setIsOpen(Constants.START_UP);
        message.setFrame(Constants.SERVER_RESPONSE_START);
        message.setLineNum(lineNum);
        ChargeSerMsg response = new ChargeSerMsg();
        response.setChargePort(startContent.getChargePort());
        response.setControll(startContent.getControll());
        response.setStartTime(startContent.getOntimeStart());
        response.setLimitData(startContent.getLimitData());
        response.setCardNum(startContent.getCardNum());
        // 协议说明可以传空
        message.setContent(response.getBytesFromMessage());
        message.setContentLength(ChargeSerMsg.length);
        message.setAddress(pileAddress);
        message.setOperator(cachePile.getOperator());
        message.setPileType(pileType);
        message.setProtocolVersion(protocol);

        logger.info("回复充电开始");
        cachePile.getChannel().writeAndFlush(message);
        return true;
    }

    /**
     * 充电桩停止充电主动上送
     *
     * @param stop ：充电桩上传给服务器的报文的实体类
     * @return message ：服务器下发给充电桩的实体类
     */
    public boolean stopCharge(CharageCeasePileMsg stop, String address, String lineNum, String protocol, int pileType) {

        // 获取缓存中桩的数据
        CachePile cachePile = GlobalManager.pileManager.getPile(address);
        if (cachePile == null) {
            logger.error("TRANS: pile {} does not exist!", address);
            return false;
        }
        // 从充电链表中删除
        ActiveMonitor.delPileFromList(cachePile);
        // 确认充电停止
        boolean b = cachePile.confirmStop(stop.getPort(), 0, stop.getCardNum());
        // 生成回复桩停止充电的报文体
        ChargeCeaseSerMsg stopResp = new ChargeCeaseSerMsg();
        stopResp.setPort(stop.getPort());
        stopResp.setControll(stop.getControll());
        stopResp.setCardNum(stop.getCardNum());
        // 生成回复报文
        MessageNew message = new MessageNew();
        message.setIsRegister(Constants.DID_REGISTER);
        if (b) {
            message.setResponse(Constants.RESPONSE_NOMAL);
        } else {
            return true;
        }
        // 停止充电后可以不需要回复
        message.setIsOpen(Constants.START_UP);
        message.setLineNum(lineNum);
        message.setFrame(Constants.SERVER_RESPONSE_STOP);
        message.setContentLength(ChargeCeaseSerMsg.length);
        message.setContent(stopResp.getBytesFromMessage());
        message.setOperator(cachePile.getOperator());
        message.setAddress(address);
        message.setPileType(pileType);
        message.setProtocolVersion(protocol);

        logger.info("回复充电结束");
        cachePile.getChannel().writeAndFlush(message);
        return true;
    }

    /**
     * 充电桩回复预约 回复内容是修改预约的开始时间
     *
     * @param reservPileMsg
     * @param pileAddress
     * @param lineNum
     */
    public boolean respReserve(ReservPileMsg reservPileMsg, String pileAddress, String lineNum, String protocol,
                               int pileType) {
        CachePile cachePile = GlobalManager.pileManager.getPile(pileAddress);
        if (cachePile == null) {
            return false;
        }
        // 调用电桩的方法确认预约成功
        // 交流电预约时，开始时间不需要传递
        return cachePile.confirmReserv(reservPileMsg.getPort(), reservPileMsg.getCardNo(), null);

        // 协议说明收到电桩确认后不需要发送确认

		/*
         * ReserveSerMsg reserveSerMsg = new ReserveSerMsg();
		 * reserveSerMsg.setCardNum(reservPileMsg.getCardNo());
		 * reserveSerMsg.setChargePort(reservPileMsg.getPort());
		 * 
		 * Message message = new Message();
		 * message.setIsOpen(Constants.START_UP); message.setLineNum(lineNum);
		 * message.setAddress(pileAddress);
		 * message.setOperator(cachePile.getOperator());
		 * message.setFrame(Constants.SERVER_RESPONSE_STOP_ORDER);
		 * message.setContentLength(ReserveCeaseSerMsg.length);
		 * message.setContent(reserveSerMsg.getBytesFromMessage());
		 * message.setResponse(Constants.RESPONSE_NOMAL);
		 * message.setIsRegister(Constants.DID_REGISTER); Channel channel =
		 * cachePile.getChannel(); if (channel == null) { return false; }
		 * channel.writeAndFlush(message);
		 */
    }

    /**
     * 充电桩停止预约主动上送
     *
     * @param stopOrder    ：停止预约充电桩的报文体
     * @param pileAddress： 充电桩设备地址
     * @return 服务器下发的报文体
     */
    public boolean stopReserve(ReserveCeasePileMsg stopOrder, String pileAddress, String lineNum, String protocol,
                               int pileType) {
        CachePile cachePile = GlobalManager.pileManager.getPile(pileAddress);
        if (cachePile == null) {
            return false;
        }
        // 确认预约取消
        cachePile.confirmReservCancelled(stopOrder.getPort(), stopOrder.getCardNum());

        ReserveCeaseSerMsg stopResponse = new ReserveCeaseSerMsg();
        stopResponse.setPort(stopOrder.getPort());
        stopResponse.setCardNum(stopOrder.getCardNum());
        // 协议说明只需要回复0x58
        MessageNew message = new MessageNew();
        message.setIsOpen(Constants.START_UP);
        message.setLineNum(lineNum);
        message.setAddress(pileAddress);
        message.setOperator(cachePile.getOperator());
        message.setFrame(Constants.SERVER_RESPONSE_STOP_ORDER);
        message.setContentLength(ReserveCeaseSerMsg.length);
        message.setContent(stopResponse.getBytesFromMessage());
        message.setResponse(Constants.RESPONSE_NOMAL);
        message.setIsRegister(Constants.DID_REGISTER);
        message.setPileType(pileType);
        message.setProtocolVersion(protocol);

        Channel channel = cachePile.getChannel();
        if (channel == null) {
            return false;
        }
        channel.writeAndFlush(message);
        return true;
    }

    /**
     * 充电桩退出登录
     *
     * @param pileAddress ：充电桩上传给服务器的报文的实体类
     * @return message：服务器下发给充电桩的实体类
     */
    public boolean unload(String pileAddress, String operatorNO, String lineNum, String protocol, int pileType) {
        CachePile cachePile = GlobalManager.pileManager.getPile(pileAddress);
        if (cachePile == null) {
            return false;
        }
        int i = cachePile.logout();
        MessageNew message = new MessageNew();
        if (i == 0) {
            message.setResponse(Constants.RESPONSE_NOMAL);
        } else {
            message.setResponse(Constants.RESPONSE_ERROR_COMMAND);
        }
        message.setIsOpen(Constants.START_UP);
        message.setIsRegister(Constants.DID_REGISTER);
        message.setLineNum(lineNum);
        message.setAddress(cachePile.getAddress());
        message.setOperator(cachePile.getOperator());
        message.setFrame(Constants.SERVER_RESPONSE_UNLOAD);
        message.setContent(null);
        message.setContentLength(0);
        message.setPileType(pileType);
        message.setProtocolVersion(protocol);

        Channel channel = cachePile.getChannel();
        if (channel == null) {
            return false;
        }
        channel.writeAndFlush(message);
        return true;
    }

    /**
     * @param stateChangePM :开始充电报文
     * @param address       :充电桩设备地址
     * @return 是否成功
     */
    public boolean changeState(StateChangePileMsg stateChangePM, String address) {

        int parameter = stateChangePM.getParameter();
        int value = stateChangePM.getValue();
        CachePile cachePile = GlobalManager.pileManager.getPile(address);
        if (cachePile == null) {
            return false;
        }
        if (parameter == StateChangePileMsg.CHARGE_STATE) {
            // 修改充电桩状态不准确
            // switch (value) {
            // case StateChangePileMsg.STATE_TRUE:
            // cachePile.changeStateCharge();
            // break;
            // case StateChangePileMsg.STATE_FALSE:
            // cachePile.changeStateIdle();
            // break;
            // }
        } else if (parameter == StateChangePileMsg.FAULT_STATE) {
            switch (value) {
                case StateChangePileMsg.STATE_TRUE:
                    cachePile.fault();
                    break;
                case StateChangePileMsg.STATE_FALSE:
                    cachePile.recovery();
                    break;
            }
        } else if (parameter == StateChangePileMsg.PLUG_STATE) {
            switch (value) {
                case StateChangePileMsg.STATE_TRUE:
                    cachePile.setInserted(true);
                    GlobalManager.pileManager.newPile(cachePile);
                    break;
                case StateChangePileMsg.STATE_FALSE:
                    cachePile.setInserted(false);
                    GlobalManager.pileManager.newPile(cachePile);
                    break;
            }
        }
        return true;
    }

    /**
     * 充电桩响应重启
     *
     * @param pileAddress
     * @return
     */
    public void restart(String pileAddress) {
        if (pileAddress == null) {
            return;
        }
        CachePile pile = GlobalManager.pileManager.getPile(pileAddress);
        if (pile == null) {
            return;
        }
        pile.confirmReboot();
    }

    /**
     * 存入账单
     *
     * @param billContent：充电桩上送的账单报文体
     * @param pileAddress：充电桩设备地址
     * @return 执行标识符 0：成功，1：失败
     */
    public boolean storeBill(BillPileMsg billContent, String pileAddress, String lineNum) {
        CachePile cachePile = GlobalManager.pileManager.getPile(pileAddress);
        if (cachePile == null) {
            return false;
        }
        // 此处账单没有账单编号
        Bill bill = new Bill();
        bill.setUserNO(billContent.getCardNum());
        bill.setPileNO(pileAddress);
        bill.setGenerateTime(TimeFormatter.toTimeYear());
        bill.setStartTime(billContent.getStartTime());
        bill.setStopTime(billContent.getEndTime());
        bill.setChargeFee(((double) billContent.getSumMoney()) / 100);
        bill.setServiceFee(((double) billContent.getserviceMon()) / 100);

        bill.setFeeSum(bill.getChargeFee() + bill.getServiceFee());
        bill.setState(billContent.getIsPay());
        bill.setPayTime(null);
        bill.setDegreeBefore(((double) billContent.getStartRecord()) / 100);
        bill.setDegreeAfter(((double) billContent.getEndRecord()) / 100);
        bill.setChargeDegree(((double) billContent.getElectricity()) / 100);
        bill.setBalanceIcBefore(((double) billContent.getStartCardMon()) / 100);
        bill.setBalanceIcAfter(((double) billContent.getEndCardMon()) / 100);

        CacheTrade cacheTrade = GlobalManager.tradeManager.getTrade(pileAddress, billContent.getCardNum());
        if (cacheTrade == null) {
            // 为刷卡账单直接创建账单
            bill.setBillNO(CommonUtils.getTID());
            bill.setPayTime(TimeFormatter.toTimeYear());
            bill.setPayWay(Bill.CARD);
            //表示刷卡的账单已经支付
            bill.setState(1);
            GlobalManager.billManager.createBill(bill);
        } else {
            logger.info("------storebill---------确认停止时交易存在------------");
            // 当交易存在时，不是刷卡账单
            cachePile.stopTrade(pileAddress, billContent.getCardNum(), billContent.getElectricity(),
                    billContent.getSumMoney());
            bill.setBillNO(cacheTrade.getTid());
            bill.setState(Bill.NO_PAY);
            cachePile.stopBill(bill);
        }
        Message message = new Message();
        message.setIsOpen(Constants.START_UP);
        message.setIsRegister(Constants.DID_REGISTER);
        message.setLineNum(lineNum);
        message.setContent(null);
        message.setContentLength(0);
        message.setFrame(Constants.SERVER_RESPONSE_BILL);
        message.setResponse(Constants.RESPONSE_NOMAL);
        message.setAddress(cachePile.getAddress());
        message.setOperator(cachePile.getOperator());
        Channel channel = cachePile.getChannel();
        if (channel == null) {
            return false;
        }
        channel.writeAndFlush(message);
        return true;
    }

    /*
     * 处理刷卡请求
     */
    public boolean card(CardPileMsg card, String pileAddress, String lineNum, String protocol, int pileType) {

        CachePile cachePile = GlobalManager.pileManager.getPile(pileAddress);
        if (cachePile == null) {
            return false;
        }

        CardSerMsg response = new CardSerMsg();
        response.setChargePort(card.getChargePort());
        response.setCardNum(card.getCardNum());
        IcUser icUser = icUserManager.select(card.getCardNum());
        if (icUser == null) {
            response.setIsValid(1);
        } else {
            response.setIsValid(0);
        }
        MessageNew message = new MessageNew();
        message.setIsOpen(Constants.START_UP);
        message.setIsRegister(Constants.DID_REGISTER);
        message.setLineNum(lineNum);
        message.setAddress(cachePile.getAddress());
        message.setContentLength(CardSerMsg.length);
        message.setContent(response.getBytesFromMessage());
        message.setFrame(Constants.SERVER_RESPONSE_CARD);
        message.setOperator(cachePile.getOperator());
        message.setResponse(Constants.RESPONSE_NOMAL);
        message.setPileType(pileType);
        message.setProtocolVersion(protocol);

        Channel channel = cachePile.getChannel();
        if (channel == null) {
            return false;
        }
        channel.writeAndFlush(message);
        return true;
    }

    public boolean queryFeeRate(String pileAddress, QueryRatePileMsg content) {
        CachePile cachePile = GlobalManager.pileManager.getPile(pileAddress);
        if (cachePile != null) {
            FeeRate feeRate = new FeeRate();
            feeRate.setOneRate(content.getOneRate());
            feeRate.setTwoRate(content.getTwoRate());
            feeRate.setThreeRate(content.getThreeRate());
            feeRate.setFourRat(content.getFourRate());
            feeRate.setTimeRate(content.getTimeRate());
            cachePile.setFeeRate(feeRate);
        }
        return true;
    }

    public boolean setFeeRate(String pileAddress, RateSettingPileMsg content) {
//		CachePile cachePile = GlobalManager.pileManager.getPile(pileAddress);
//		if (cachePile == null) {
//			return false;
//		}
        return true;
    }

    // 从消息中获取遥测数据，设置到cachepile对象
    public boolean getRemoteMetric(String pileAddress, TelemetryPileMsg rmMsg) {
        CachePile cachePile = GlobalManager.pileManager.getPile(pileAddress);
        if (cachePile == null) {
            return false;
        }
        cachePile.setVoltage(rmMsg.getVoltage());
        cachePile.setCurrent(rmMsg.getCurrent());
        cachePile.setHours(rmMsg.getHours());
        cachePile.setMinutes(rmMsg.getMinutes());
        cachePile.setPower(rmMsg.getPower());
        // logger.debug("Pile[{}]: voltage {}, current {}, hour {}, minutes {},
        // power {}.",
        // pileAddress, rmMsg.getVoltage(), rmMsg.getCurrent(),
        // rmMsg.getHours(),
        // rmMsg.getMinutes(), rmMsg.getPower());

        // 电桩数据刷新到前台，websocket
        cachePile.refreshUI();
        return true;
    }

    // 从消息中获取遥信数据，设置到cachepile对象
    public boolean getRemoteSignal(String pileAddress, SignPileMsg rsMsg) {
        CachePile cachePile = GlobalManager.pileManager.getPile(pileAddress);
        if (cachePile == null) {
            return false;
        }
        int plug = rsMsg.getPlug();
        boolean inserted = false;
        if (plug == 1) {
            inserted = true;
        }
        int fault = rsMsg.getFault();
        if (fault == 0) {
            cachePile.setFault("00");
        } else {
            cachePile.setFault("01");
        }
        cachePile.setInserted(inserted);
        //GlobalManager.pileManager.newPile(cachePile);
        return true;
    }

    // 从消息中获取遥脉数据，设置到cachepile对象
    public boolean getRemotePulse(String pileAddress, PlusePileMsg rpMsg) {
        CachePile cachePile = GlobalManager.pileManager.getPile(pileAddress);
        if (cachePile == null) {
            return false;
        }
        cachePile.setElectricity(rpMsg.getElectricity());
        cachePile.setMoney(rpMsg.getMoney());
        // logger.debug("Pile[{}]: electricity {}, money {}.",
        // pileAddress, rpMsg.getElectricity(), rpMsg.getMoney());

        // 电桩数据刷新到前台
        cachePile.refreshUI();
        return true;
    }
}